
//双检查锁：双检查锁：//https://blog.csdn.net/bdss58/article/details/44813597

#include <limits>
#include <vector>
#include <math.h>
#include <iostream>

using namespace std;

// 饿汉式
class Singleton
{
public:
	static Singleton& getInstance()
	{		
		return instance;//第一次调用时才会调用构建函数
	}
  ~Singleton(){ cout << "单例对象销毁！" << endl; };
private:
	Singleton() { cout << "单例对象创建！" << endl; };
	Singleton(const Singleton &) = delete;
	Singleton& operator=(const Singleton &) =delete;

 private:
  	static Singleton instance; // 单例对象在这里！
};
Singleton Singleton::instance;//直接生成一个全局性的对象

class Singleton2
{
public:
	static Singleton2& getInstance()
	{	
		static Singleton2 instance;//第一次用到时才创建对象
		return instance;
	}
  ~Singleton2(){ cout << "单例对象销毁 Singleton2!" << endl; };
private:
	Singleton2(){ cout << "单例对象创建 Singleton2!" << endl; };
	Singleton2(const Singleton2 &) = delete;
	Singleton2& operator=(const Singleton2 &) = delete;
};

// std::call_once 
#include <memory>
#include <atomic>
#include <thread>
#include <mutex>

class Singleton {
public:
  static Singleton& GetInstance() {
    static std::once_flag s_flag;
    std::call_once(s_flag, [&]() {
      instance_.reset(new Singleton);
    });
    return *instance_;
  }

  ~Singleton() = default;

  void PrintAddress() const {
    std::cout << this << std::endl;
  }

private:
  Singleton() = default;

  Singleton(const Singleton&) = delete;
  Singleton& operator=(const Singleton&) = delete;

private:
  static std::unique_ptr<Singleton> instance_;
};